/*
 * Copyright (C) 2022 KylinSoft Co., Ltd.
 *
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see <https://www.gnu.org/licenses/>.
 */

#include "desktopbackground.h"
#include <QGuiApplication>

DesktopBackground::DesktopBackground(QQuickPaintedItem *parent) : QQuickPaintedItem(parent)
{
    if (QGSettings::isSchemaInstalled("org.mate.background")) {
        m_backgroundGSettings = new QGSettings("org.mate.background");
        if(m_backgroundGSettings->get("pictureFilename").toString() == NULL){
            setbackgroundColor(m_backgroundGSettings->get("primaryColor").toString());
        }else {
            setBackground(m_backgroundGSettings->get("pictureFilename").toString());
        }
        setImagestate(m_backgroundGSettings->get("pictureOptions").toString());
        connect(m_backgroundGSettings, &QGSettings::changed, [this](const QString &key) {
            if (key == "pictureFilename") {
                setBackground(m_backgroundGSettings->get("pictureFilename").toString());
            }
            if (key == "pictureOptions") {
                setImagestate(m_backgroundGSettings->get("pictureOptions").toString());
            }
            if (key == "primaryColor") {
                setbackgroundColor(m_backgroundGSettings->get("primaryColor").toString());
            }
        });
    }
}

void DesktopBackground::paint(QPainter *painter)
{
    painter->setRenderHint(QPainter::SmoothPixmapTransform);
    painter->setRenderHint(QPainter::Antialiasing,true);
    painter->save();
    if(m_background == NULL){
        return;
    }
    QPixmap backPixmap = QPixmap(m_background);
    m_screen = QGuiApplication::primaryScreen();

    if (m_imageState == "centered")    {
        //居中
        painter->drawPixmap((m_screen->size().width() - backPixmap.rect().width()) / 2,
                     (m_screen->size().height() - backPixmap.rect().height()) / 2,
                     backPixmap);
    } else if (m_imageState == "wallpaper") {
        //平铺
        int drawedWidth = 0;
        int drawedHeight = 0;

        while (1) {
            drawedWidth = 0;
            while (1) {
                painter->drawPixmap(drawedWidth, drawedHeight, backPixmap);
                drawedWidth += backPixmap.width();
                if (drawedWidth >= m_screen->size().width()) {
                    break;
                }
            }
            drawedHeight += backPixmap.height();
            if (drawedHeight >= m_screen->size().height()) {
                break;
            }
        }
    } else if (m_imageState == "scaled") {
        //填充
        painter->drawPixmap(m_screen->geometry(), backPixmap, getSourceRect(backPixmap));
    } else if (m_imageState == "stretched") {
        //拉伸
        painter->drawPixmap(m_screen->geometry(), backPixmap, backPixmap.rect());
    }
    else {
        //默认填充方式
        painter->drawPixmap(m_screen->geometry(), backPixmap, getSourceRect(backPixmap));
    }
    painter->restore();
}

QString DesktopBackground::background() const
{
    return m_background;
}

void DesktopBackground::setBackground(const QString &background)
{
    if (m_background != background) {
        m_background = background;
        update();
        Q_EMIT backgroundChanged();
    }
}

QString DesktopBackground::imagestate() const
{
    return m_imageState;
}

void DesktopBackground::setImagestate(const QString &imagestate)
{
    if (m_imageState != imagestate) {
        m_imageState = imagestate;
        update();
        Q_EMIT imageStateChanged();
    }
}

QString DesktopBackground::backgroundColor() const
{
    return m_background;
}

void DesktopBackground::setbackgroundColor(const QString &backgroundColor)
{
    if (m_background != backgroundColor) {
        qDebug()<<"===DesktopBackground::setbackgroundColor";
        m_background = backgroundColor;
        Q_EMIT backgroundColorChanged();
    }
}

QPixmap DesktopBackground::getBackPixmap() const
{
    return m_backPixmap;
}

QPixmap DesktopBackground::getFrontPixmap() const
{
    return m_frontPixmap;
}

QRect DesktopBackground::getSourceRect(const QPixmap &pixmap)
{
    qreal screenScale = qreal(m_screen->geometry().width()) / qreal(m_screen->geometry().height());
    qreal width = pixmap.width();
    qreal height = pixmap.height();

    if ((width / height) == screenScale) {
        return pixmap.rect();
    }

    bool isShortX = (width <= height);
    if (isShortX) {
        screenScale = qreal(m_screen->geometry().height()) / qreal(m_screen->geometry().width());
    }

    qreal shortEdge = isShortX ? width : height;
    qreal longEdge = isShortX ? height : width;

    while (shortEdge > 1) {
        qint32 temp = qFloor(shortEdge * screenScale);
        if (temp <= longEdge) {
            longEdge = temp;
            break;
        }

        qint32 spacing = qRound(shortEdge / 20);
        if (spacing <= 0) {
            spacing = 1;
        }
        shortEdge -= spacing;
    }

    QSize sourceSize = pixmap.size();
    if (shortEdge > 1 && longEdge > 1) {
        sourceSize.setWidth(isShortX ? shortEdge : longEdge);
        sourceSize.setHeight(isShortX ? longEdge : shortEdge);
    }

    qint32 offsetX = 0;
    qint32 offsetY = 0;
    if (pixmap.width() > sourceSize.width()) {
        offsetX = (pixmap.width() - sourceSize.width()) / 2;
    }

    if (pixmap.height() > sourceSize.height()) {
        offsetY = (pixmap.height() - sourceSize.height()) / 2;
    }

    QPoint offsetPoint = pixmap.rect().topLeft();
    offsetPoint += QPoint(offsetX, offsetY);

    return QRect(offsetPoint, sourceSize);
}

